home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianFontSystem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
12KB
|
553 lines
/* ScianFontSystem.c
Routines for font system and string utilities
Jim Lyons
7/26/91
9/24/91 added support for raster fonts
1/5/92 EMP added font counting for both types of fonts
1/28/92 modified StrWidth and DrawString to handle tabs
4/6/92 added PostScript drawing mode
9/14/92 changed DrawString to take alignment parameter
and changed name to DrawAString
9/10/93 added SetUIFont
*/
#include "Scian.h"
#include "ScianStyle.h"
#include "ScianTypes.h"
#include "ScianFontSystem.h"
#include "ScianWindows.h"
#include "ScianDraw.h"
#include "ScianTextBoxes.h"
#ifdef GRAPHICS
#include "ScianPalatino18.h"
#include "ScianTitleFont.h"
#define NRASTERFONTS 4 /* NOT including system font or icon fonts */
#define SCIANTITLE 1
#define MAXFONTSUSED 10 /* max different fonts in window (for PS drawing) */
#endif
#ifndef TABWID
#define TABWID 4 /* number of 'chars' per tab stop */
#endif
/*
The font system handles font manager routines, if available, as
well as raster fonts. When SetupFont is called, the font name
is first looked up using fmfindfont. If found, the font is scaled
to size and currentFontHandle is set for use by subsequent calls
to DrawAString, StringWidth, etc. If fmfindfont fails (or if not
FONTS4D) currentFontHandle is set to NULL and the name is looked
up in the raster font name table, rasterFont[]. (The size parameter
is ignored.) If not found the system font is used.
Note that icon fonts are not treated like text fonts, although they
are initialized here in InitFonts.
*/
/* globals for font system */
#ifdef GRAPHICS
char *rasterFont[NRASTERFONTS + 1]; /* table of raster font name pointers */
int nFonts = 0;
char **fonts;
static int registeredFonts;
char curFontName[64]; /* remember which font is set */
int curFontSize;
#ifdef FONTS4D
fmfonthandle currentFontHandle = NIL;
#endif
struct fontinfo uiFontInfo[NUIFONTS] =
{
"Helvetica-BoldOblique", 12, 0,
"Helvetica", 10, 0,
"Helvetica", 12, 0,
"Helvetica", 14, 0,
"Helvetica", 18, 0,
"Helvetica-Bold", 10, 0,
"Helvetica-Bold", 12, 0,
"Helvetica-Bold", 14, 0,
"Helvetica-Bold", 18, 0
};
#endif
char *fontsUsed[MAXFONTSUSED]; /* list of fonts used in PostScript file */
int numFontsUsed = 0; /* number of fonts used = next index */
char showBuf[256]; /* string buffer for PostScript show */
static void CountFonts(s)
char *s;
/*Counts the fonts*/
{
#ifdef GRAPHICS
++nFonts;
#endif
}
static void RegisterFont(s)
char *s;
/*Puts the font names in a list, fonts[]*/
{
#ifdef GRAPHICS
fonts[registeredFonts] = Alloc(strlen(s) + 1);
strcpy(fonts[registeredFonts], s);
++registeredFonts;
#endif
}
#ifdef PROTO
static int CompareFonts(const void *f1, const void *f2)
#else
static int CompareFonts(f1, f2)
void *f1;
void *f2;
#endif
/*Compares two font names*/
{
return strcmp2(*(char **) f1, *(char **) f2);
}
#ifdef PROTO
static void SortFonts(void)
#else
static void SortFonts()
#endif
{
/*Sorts the fonts*/
qsort(fonts, registeredFonts, sizeof(char *), CompareFonts);
}
void InitFonts(void) /*********************************** INITFONTS */
{
#ifdef GRAPHICS
int i;
#ifdef FONTS4D
fmfonthandle fh;
#endif
nFonts = 2;
#ifdef FONTS4D
fminit();
fmenumerate(CountFonts);
#endif
fonts = (char**) Alloc(sizeof(char *) * nFonts);
#ifdef FONTS4D
/* register fonts for font menu */
registeredFonts = 0;
fmenumerate(RegisterFont);
#endif
/*Complete font menu with System and Palatino18*/
RegisterFont("System");
RegisterFont("Palatino18");
SortFonts();
rasterFont[0] = "System"; /* default */
for (i=1; i<NRASTERFONTS+1; ++i) rasterFont[i] = "\0";
#ifdef BIGFONTSOK
rasterFont[TITLEFONT] = "ScianTitle";
defrasterfont(TITLEFONT, ScianTitleFontHT, ScianTitleFontNC, ScianTitleFontchars,
ScianTitleFontRS, (void *) ScianTitleFontrasters);
#endif
rasterFont[SUBTITLEFONT] = "Palatino18";
defrasterfont(SUBTITLEFONT, palatino18HT, palatino18NC, stChars,
palatino18RS, (void *) stRasters);
numFontsUsed = 0;
strcpy(curFontName, "System");
curFontSize = 10;
#ifdef FONTS4D
/* set up fonts for user interface */
/* Regular fonts */
fh = fmfindfont(uiFontInfo[UISMALLFONT].name);
if (fh)
{
uiFontInfo[UISMALLFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UISMALLFONT].size);
uiFontInfo[UINORMALFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UINORMALFONT].size);
uiFontInfo[UILARGEFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UILARGEFONT].size);
uiFontInfo[UITITLEFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UITITLEFONT].size);
}
/* Bold fonts */
fh = fmfindfont(uiFontInfo[UIBOLDSMALLFONT].name);
if (fh)
{
uiFontInfo[UIBOLDSMALLFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UIBOLDSMALLFONT].size);
uiFontInfo[UIBOLDNORMALFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UIBOLDNORMALFONT].size);
uiFontInfo[UIBOLDLARGEFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UIBOLDLARGEFONT].size);
uiFontInfo[UIBOLDTITLEFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UIBOLDTITLEFONT].size);
}
else
{
uiFontInfo[UIBOLDSMALLFONT].fontHandle =
uiFontInfo[UISMALLFONT].fontHandle;
uiFontInfo[UIBOLDNORMALFONT].fontHandle =
uiFontInfo[UINORMALFONT].fontHandle;
uiFontInfo[UIBOLDLARGEFONT].fontHandle =
uiFontInfo[UILARGEFONT].fontHandle;
uiFontInfo[UIBOLDTITLEFONT].fontHandle =
uiFontInfo[UITITLEFONT].fontHandle;
}
/* menu font */
fh = fmfindfont(uiFontInfo[UIMENUFONT].name);
if (fh)
{
uiFontInfo[UIMENUFONT].fontHandle = (char **)
fmscalefont(fh, uiFontInfo[UIMENUFONT].size);
}
else
{
if (uiFontInfo[UIBOLDNORMALFONT].fontHandle)
uiFontInfo[UIMENUFONT].fontHandle =
uiFontInfo[UIBOLDNORMALFONT].fontHandle;
else uiFontInfo[UIMENUFONT].fontHandle =
uiFontInfo[UINORMALFONT].fontHandle;
}
#endif
#endif
}
void KillFonts(void)
{
#ifdef GRAPHICS
int k;
/*** free memory ***/
for (k = 0; k < nFonts; ++k)
{
Free(fonts[k]);
}
if (fonts)
{
Free(fonts);
}
#endif
}
#ifdef PROTO
Bool SetupFont(char *name, int size)
#else
Bool SetupFont(name, size)
char *name;
int size;
#endif
{
#ifdef GRAPHICS
int i;
if (drawingMode == DRAW_SCREEN)
{
#ifdef FONTS4D
currentFontHandle = fmfindfont(name);
if (currentFontHandle)
{
currentFontHandle = fmscalefont(currentFontHandle, size);
fmsetfont(currentFontHandle);
return true;
}
else
{
currentFontHandle = NIL;
for (i=1; i<NRASTERFONTS+1; ++i)
{
if (strcmp(name, rasterFont[i]) != 0) continue;
font(i);
return true;
}
font(0);
return false;
}
#else
for (i=1; i<NRASTERFONTS+1; ++i)
{
if (strcmp(name, rasterFont[i]) != 0) continue;
font(i);
return true;
}
font(0);
return false;
#endif
}
else if (drawingMode == DRAW_POSTSCRIPT && psFile)
{
/* see if same as current font and size */
if (strcmp(name, curFontName) == 0 && size == curFontSize) return true;
RegisterFontUsed(name); /* add to list for PS file trailer */
strcpy(curFontName, name); /* remember this */
curFontSize = size;
/* write PostScript to drawing file to set up font */
/* size is made larger by 2 points to adjust for screen vs printer */
fprintf(psFile, "/%s findfont %d scalefont setfont\n", name, size+2);
return true;
}
#endif
return false;
}
#ifdef PROTO
void SetUIFont(int uiFontNum)
#else
void SetUIFont(uiFontNum)
int uiFontNum;
#endif
{
#ifdef GRAPHICS
if (drawingMode == DRAW_SCREEN)
{
#ifdef FONTS4D
currentFontHandle = (fmfonthandle) uiFontInfo[uiFontNum].fontHandle;
fmsetfont(currentFontHandle);
#else
font(0);
#endif
}
else if (drawingMode == DRAW_POSTSCRIPT && psFile)
{
/* see if same as current font and size */
if (strcmp(uiFontInfo[uiFontNum].name, curFontName) == 0
&& uiFontInfo[uiFontNum].size == curFontSize) return;
RegisterFontUsed(uiFontInfo[uiFontNum].name);
strcpy(curFontName, uiFontInfo[uiFontNum].name); /* remember this */
curFontSize = uiFontInfo[uiFontNum].size;
/* write PostScript to drawing file to set up font */
/* size is made larger by 2 points to adjust for screen vs printer */
fprintf(psFile, "/%s findfont %d scalefont setfont\n",
uiFontInfo[uiFontNum].name, uiFontInfo[uiFontNum].size+2);
}
#endif
}
#ifdef PROTO
void RegisterFontUsed(char *name)
#else
void RegisterFontUsed(name)
char *name;
#endif
{
/* for PostScript file output--makes list of fonts used for trailer */
#ifdef GRAPHICS
int i;
/* check list of fonts used */
for (i = 0; i < numFontsUsed; ++i)
{
if (strcmp(name, fontsUsed[i]) == 0) return;
}
if (numFontsUsed >= MAXFONTSUSED)
{
ReportError("RegisterFontUsed","Too many fonts!");
return;
}
fontsUsed[numFontsUsed] = Alloc(strlen(name) + 1);
if (fontsUsed[numFontsUsed])
{
strcpy(fontsUsed[numFontsUsed], name);
++numFontsUsed;
}
else OMErr();
#endif
return;
}
#ifdef PROTO
int ChrWidth(char c)
#else
int ChrWidth(c)
char c;
#endif
{
#ifdef GRAPHICS
if (c < ' ') return 0;
#ifdef FONTS4D
if (currentFontHandle)
{
return fmgetchrwidth(currentFontHandle, c);
}
else
{
char buf[2];
buf[0] = c;
buf[1] = '\0';
return strwidth(buf);
}
#else
{ char buf[2];
buf[0] = c;
buf[1] = '\0';
return strwidth(buf);
}
#endif
#else
return 0;
#endif
}
#ifdef PROTO
int StrWidth(char *s)
#else
int StrWidth(s)
char *s;
#endif
/* handles tabs in string */
{
#ifdef GRAPHICS
int nTabs=0;
char *t=s;
while (*t)
{
if (*t++ == '\t')
{
s = t; /* point to char following tab */
++nTabs; /* incr tab count */
}
}
/* now return the indent plus the length of the string following last tab */
#ifdef FONTS4D
if (currentFontHandle)
{
return nTabs*TABWID*ChrWidth('0') + fmgetstrwidth(currentFontHandle, s);
}
else
{
return nTabs*TABWID*ChrWidth('0') + strwidth(s);
}
#else
return nTabs*TABWID*ChrWidth('0') + strwidth(s);
#endif
#else
return 0;
#endif
}
#ifdef PROTO
char *show(char *s)
#else
char *show(s)
char *s;
#endif
{
/*
* Process any special characters in string for PostScript show.
*/
char *p = showBuf;
while (*s)
{
if (*s == '(' || *s == ')' || *s == '\\') *p++ = '\\';
*p++ = *s++;
}
*p = '\0';
return showBuf;
}
#ifdef PROTO
void DrawAString(int align, long x, long y, char *s)
#else
void DrawAString(align, x, y, s)
int align;
long x, y;
char *s;
#endif
{
#ifdef GRAPHICS
int left, right, bottom, top;
int xx, yy, dxx, dyy;
if (drawingMode == DRAW_SCREEN)
{
/* find starting point of string */
switch (align)
{
case RIGHTALIGN:
x -= StrWidth(s);
break;
case CENTERALIGN:
x -= StrWidth(s)/2;
break;
case LEFTALIGN:
default:
break;
}
/* check to see if string starts out of window */
GetWindowBounds(&left, &right, &bottom, &top);
CurOffset(&xx, &yy);
GetWindowOrigin(&dxx, &dyy);
left -= xx - dxx;
/* trim string if necessary */
while (x < left)
{
if (*s == '\0') return;
x += ChrWidth(*s++);
}
cmov2i(x, y);
#ifdef FONTS4D
if (currentFontHandle)
{
fmprstr(s);
}
else
{
charstr(s);
}
#else
charstr(s);
#endif
}
else if (drawingMode == DRAW_POSTSCRIPT && psFile && *s != '\0')
{
/* write PostScript to file */
fprintf(psFile, "%f setgray\n", PSColor());
switch (align)
{
case RIGHTALIGN:
fprintf(psFile,
"(%s) dup %d exch stringwidth pop sub %d moveto show\n", show(s), x, y);
break;
case CENTERALIGN:
fprintf(psFile,
"(%s) dup %d exch stringwidth pop 2 div sub %d moveto show\n", show(s), x, y);
break;
case LEFTALIGN:
default:
fprintf(psFile, "%d %d moveto (%s) show\n", x, y, show(s));
break;
}
}
#endif
}